import java.io.IOException;
import java.net.SocketException;
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class RMISpellingServer
{

	/**
	 * The minimum valid port number.
	 */
	public static final int MIN_PORT_NUMBER = 1024;

	/**
	 * The maximum valid port number.
	 */
	public static final int MAX_PORT_NUMBER = 65535;

	private int my_port;
	private String my_servicename;
	private Registry my_registry;
	private RemoteSpelling my_remotespelling;

	public RMISpellingServer(String[] the_args) throws SocketException
	{
		if (the_args.length != 3)
		{
			System.err.println("Usage: java RMISpellingServer <port> <service-name> <word-list>");
			System.exit(1);
		}
		this.my_port = getPort(the_args);
		this.my_servicename = getservicename(the_args);
		this.my_registry = getregistry(my_port);
		this.my_remotespelling = my_remotespelling;
	}

	/**
	 * Get the port number.
	 * 
	 * @param the_args
	 *            the input string
	 * @return the port number
	 */
	private int getPort(final String[] the_args)
	{
		int iport = 0;
		try
		{
			iport = Integer.parseInt(the_args[0]);
			Log.out("Successful get the port number.");
		} 
		catch (final NumberFormatException e)
		{
			System.err.println("Port number must be numeric");
			System.exit(1);
		}
		if (iport < MIN_PORT_NUMBER || iport > MAX_PORT_NUMBER)
		{
			System.err.println("Port number must be between " + MIN_PORT_NUMBER
					+ " and " + MAX_PORT_NUMBER + " inclusive.");
			System.exit(1);
		}
		return iport;
	}

	private String getservicename(String[] the_args)
	{
		String temp = null;
		try
		{
			temp = the_args[1];
			Log.out("Successfully get the service name.");

		} catch (Exception e)
		{
			System.err.println("Cannot get the service name. " + e);
		}
		return temp;
	}
	
	private Registry getregistry(int i)
	{
		Registry temp = null;
		try
		{
			temp = LocateRegistry.createRegistry(i);
			Log.out("Successfully registered as name " + temp.getClass().getName());
			
		} catch (RemoteException e)
		{
			System.err.println("Problem exporting the service.");
			e.printStackTrace();
		}
		return temp;
	}


	public static void main(String[] args) throws SocketException
	{
		RMISpellingServer server = new RMISpellingServer(args);
		try
		{
			Object temp = UnicastRemoteObject.exportObject(server.my_remotespelling= new UnicastRemoteSpelling(args[2]),0);
			server.my_registry.bind(server.my_servicename, (Remote) temp);
			Log.out("Successfully exported spelling service as " + server.my_servicename + " on port " + server.my_port);		
		} 
		catch (RemoteException e)
		{
			System.err.println("Problem exporting the service.");
			e.printStackTrace();
		}
		catch (IOException e)
		{
			System.err.println("Problem loading word list.");
			e.printStackTrace();
		}
		catch (AlreadyBoundException e)
		{
			System.err.println("Service has already bound");
			e.printStackTrace();
		}

	}

}
